﻿#region - 版 本 注 释 -
/*----------------------------------------------------------------
 * 版权所有 (c) 2025   保留所有权利。
 * CLR版本：4.0.30319.42000
 * 机器名称：DESKTOP-GLJ2Q8J
 * 公司名称：
 * 命名空间：AutoCAD.EntityTools
 * 唯一标识：1ef392ce-4fbc-4c68-bb2f-a9416cc2aceb
 * 文件名：LineTools
 * 当前用户域：DESKTOP-GLJ2Q8J
 * 
 * 创建者：Guoweihao-79991
 * 电子邮箱：799919859@qq.com
 * 创建时间：2025/5/23 16:28:20
 * 版本：V1.0.0
 *
 * 功能描述(Description):
 * 参考文档(Reference):
 * 数据表(Tables):
 * 作者(Author):Guo
 *
 * ----------------------------------------------------------------
 * 修改人：
 * 时间：
 * 修改说明：
 *
 * 版本：V1.0.1
 *----------------------------------------------------------------*/
#endregion - 版 本 注 释 -

namespace AutoCAD.EntityTools
{
    /// <summary>
    /// 圆弧工具类
    /// </summary>
    public static class ArcTools
    {
        /// <summary>
        /// 计算两条平行圆弧之间的最短垂直距离
        /// </summary>
        /// <param name="arc1">第一条圆弧</param>
        /// <param name="arc2">第二条圆弧</param>
        /// <param name="tolerance">几何容差（默认1e-5）</param>
        /// <returns>圆弧间的最短垂直距离，若不平行返回double.NaN</returns>
        /// 
        [Obsolete("不稳定")]
        public static double CalculateShortestDistanceBetweenParallelArcs(this Arc arc1, Arc arc2, double tolerance = 1e-5)
        {
            // 1. 输入有效性检查
            if (arc1 == null || arc2 == null)
                return double.NaN;

            // 2. 法向量平行性检查（考虑反向平行）
            Vector3d normal1 = arc1.Normal.GetNormal();
            Vector3d normal2 = arc2.Normal.GetNormal();

            //误差问题取消平行验证
            // if (!normal1.IsParallelTo(normal2, Autodesk.AutoCAD.Geometry.Tolerance.Global))
            //   return double.NaN;

            // 3. 计算圆心连线向量
            Vector3d centerVector = arc2.Center - arc1.Center;

            // 4. 验证真实平行性（圆心连线必须与法向量垂直）
            //if (Math.Abs(centerVector.DotProduct(normal1)) > tolerance)
            //  return double.NaN;

            // 5. 计算理论最短距离（考虑半径差）
            double centerDistance = centerVector.Length;
            double radiusDiff = Math.Abs(arc1.Radius - arc2.Radius);

            // 6. 处理同心圆弧特殊情况
            if (centerDistance < tolerance)
                return radiusDiff;

            // 7. 实际距离计算（勾股定理）
            return Math.Sqrt(centerDistance * centerDistance + radiusDiff * radiusDiff);
        }




        /// <summary>
        /// 判断两条圆弧是否平行且距离符合要求
        /// </summary>
        /// <param name="arc1">第一个圆弧</param>
        /// <param name="arc2">第二个圆弧</param>
        /// <param name="expectedDistance">距离</param>
        /// <param name="distanceTolerance">误差</param>
        /// <returns></returns>
        public static bool AreArcsParallelAndAtDistance(this Arc arc1, Arc arc2,
            double expectedDistance, double distanceTolerance)
        {
            // 检查圆弧是否在同一平面且法向量平行
            if (!arc1.Normal.IsParallelTo(arc2.Normal))
                return false;

            // 检查圆心距离是否符合预期
            double centerDistance = arc1.Center.DistanceTo(arc2.Center);
            double radiusDifference = Math.Abs(arc1.Radius - arc2.Radius);

            // 同心圆弧或半径差等于预期距离
            return Math.Abs(radiusDifference - expectedDistance) <= distanceTolerance ||
                   (centerDistance <= distanceTolerance &&
                    Math.Abs(arc1.Radius - arc2.Radius - expectedDistance) <= distanceTolerance);
        }



        /// <summary>
        /// 增强版平行距离判断（支持直线和圆弧）
        /// </summary>
        public static bool AreWallsParallelAndAtDistanceEnhanced(
            this Curve wall1,
            Curve wall2,
            double[] allowedDistances,
            double distanceTolerance = 0.001)
        {
            // 检查所有允许的距离
            foreach (double expectedDistance in allowedDistances)
            {


                // 直线-直线情况
                if (wall1 is Line line1 && wall2 is Line line2)
                {



                    //首先判断厚度,保证分组正确性
                    var thickness = (wall1 as Line).CalculateShortestDistanceBetweenParallelLines(wall2 as Line , distanceTolerance);
                    //起始点
                    var wallStart = wall1.StartPoint;
                    var wallEnd = wall1.EndPoint;
                    var candidateStart = wall2.StartPoint;
                    var candidateEnd = wall2.EndPoint;

                    var isWallLine = true;
                    foreach (var alldis in allowedDistances)
                    {
                        //if ((thickness - alldis < distanceTolerance) && (wallStart.DistanceTo(candidateStart) - alldis < distanceTolerance)
                        //    || (wallStart.DistanceTo(candidateEnd) - alldis < distanceTolerance) ||
                        //    (wallEnd.DistanceTo(candidateEnd) - alldis < distanceTolerance) || 
                        //    (wallEnd.DistanceTo(candidateStart) - alldis < distanceTolerance))
                        if ((Math.Abs(thickness - alldis) < distanceTolerance) &&
                               (Math.Abs(line1.StartPoint.DistanceTo(line2.StartPoint) - alldis) < distanceTolerance ||
                                Math.Abs(line1.StartPoint.DistanceTo(line2.EndPoint) - alldis) < distanceTolerance ||
                                Math.Abs(line1.EndPoint.DistanceTo(line2.EndPoint) - alldis) < distanceTolerance ||
                                Math.Abs(line1.EndPoint.DistanceTo(line2.StartPoint) - alldis) < distanceTolerance))
                        {
                            isWallLine = true;
                            break;
                        }
                        else
                            isWallLine = false;
                    }







                    if (AreLinesParallelAndAtDistance(line1, line2, expectedDistance, distanceTolerance) && isWallLine)
                        return true;
                }
                // 圆弧-圆弧情况
                else if (wall1 is Arc arc1 && wall2 is Arc arc2)
                {
                    if (arc1.AreArcsParallelAndAtDistance(arc2, expectedDistance, distanceTolerance))
                        return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 误差值去全局
        /// </summary>
        public static Tolerance tolerance { get; set; } = new Autodesk.AutoCAD.Geometry.Tolerance(0.001, 0.001);
        /// <summary>
        /// 判断两条直线是否平行且距离符合要求
        /// </summary>
        public static bool AreLinesParallelAndAtDistance(Line line1, Line line2,
            double expectedDistance, double distanceTolerance)
        {

            //var eq = new Autodesk.AutoCAD.Geometry.Tolerance(0.001, 0.001);

            Vector3d dir1 = (line1.EndPoint - line1.StartPoint).GetNormal();
            Vector3d dir2 = (line2.EndPoint - line2.StartPoint).GetNormal();

            if (!dir1.IsParallelTo(dir2, tolerance) && !dir1.IsParallelTo(-dir2, tolerance))
                return false;

            double actualDistance = line1.CalculateShortestDistanceBetweenParallelLines(line2 , distanceTolerance);
            return Math.Abs(actualDistance - expectedDistance) <= distanceTolerance;
        }

    }
}
